<?php
/**
 * 请求的上下文
 *
 * @since 1.0
 * @package if
 * @subpackage controller.context
 */
class IContext extends IMagicObject {
	private static $instance;
	
	private function __construct() {
		
	}
	
	/**
	 * Enter description here...
	 *
	 * @return IContext
	 */
	static function singleton() {
		if (!self::$instance) {
			self::$instance = new self;
		}
		return self::$instance;
	}
	
	private function _type(&$key) {
		$key = strval($key);
		if (strlen($key) < 1) {
			return "request";
		}
		$prefix = $key{0};
		if (in_array($prefix, array("!", "#", "*", "%", "@", "~"))) {
			$key = substr($key, 1);
			switch ($prefix) {
				case "!":
					return "flash";
				case "#":
					return "session";
				case "*":
					return "cookie";
				case "%":
					return "request";
				case "@":
					return "config";
				case "~":
					return "message";
			}
		}
		return "request";
	}
	
	/**
	 * Enter description here...
	 *
	 * @return IFlash
	 */
	function flash() {
		return IFlash::singleton();
	}
	
	/**
	 * Enter description here...
	 *
	 * @return ISession
	 */
	function session() {
		return ISession::singleton();
	}
	
	/**
	 * Enter description here...
	 *
	 * @return IRequest
	 */
	function request() {
		return IRequest::singleton();
	}
	
	/**
	 * Enter description here...
	 *
	 * @return IResponse
	 */
	function response() {
		return IResponse::singleton();
	}
	
	/**
	 * 判断键是否存在
	 * 
	 * 使用 isset($object[$key]) 时激活
	 *
	 * @param mixed $key 键
	 * @return boolean
	 * @since 1.0
	 */
	function offsetExists($key) {
		switch ($this->_type($key)) {
			case "flash":
				return $this->flash()->contains($key);
			case "session":
				return $this->session()->contains($key);
			case "cookie":
				return !is_null(ICookie::get($key));
			case "request":
				return !is_null($this->request()->param($key));
			case "config":
				return !is_null(o("@" . $key));
			case "message":
				return !is_null(ILocale::current()->message($key));
		}
		return false;
	}
	
	/**
	 * 取得键的值
	 * 
	 * 使用 echo $object[$key] 时激活
	 *
	 * @param mixed $key 键
	 * @return mixed
	 * @since 1.0
	 */
	function offsetGet($key) {
		if (empty($key)) {
			return $this->request()->params();
		}
		else {
			$type = $this->_type($key);//此时的key去掉了前缀
			$value = null;
			
			if (empty($key)) {
				switch ($type) {
					case "flash": $value = $this->flash()->all(); break;
					case "session":$value = $this->session()->all(); break;
					case "cookie": $value = ICookie::all(); break;
					case "request": $value = $this->request()->params(); break;
					case "config": $value = IConfig::opt("@");break;
					case "message": $value = ILocale::current()->messages(); break;
				}
				return $value;
			}
			else {
				$keys = explode(".", $key);
				$key = $keys[0];
				unset($keys[0]);
				
				switch ($type) {
					case "flash": $value = $this->flash()->get($key); break;
					case "session": $value = $this->session()->get($key); break;
					case "cookie": $value =  ICookie::get($key); break;
					case "request": $value = $this->request()->param($key); break;
					case "config": $value = o("@" . $key); break;
					case "message": $value = ILocale::current()->message($key); break;
				}
				return is_array($value) ? if_array_get($value, $keys) : $value;
			}
		}
	}
	
	
	/**
	 * 设置键的值
	 * 
	 * 使用 $object[$key] = $value; 时激活
	 *
	 * @param mixed $key 键
	 * @param mixed $item 键的值
	 * @since 1.0
	 */	
	function offsetSet($key, $item) {
		switch ($this->_type($key)) {
			case "flash":
				$this->flash()->set($key, $item);
				break;
			case "session":
				$this->session()->set($key, $item);
				break;
			case "cookie":
				$cookie = new ICookie($key, $item);
				if (is_null($cookie->path())) {
					$cookie->setPath("/");
				}
				$cookie->send();
				break;
			case "request":
				$this->request()->addParam($key, $item);
				break;
			case "config":
				o("@{$key}", $item);
				break;	
			case "message":
				break;
			default:
				$this->request()->addParam($key, $item);
		}
	}
	
	/**
	 * 销毁键对应的元素
	 * 
	 * 使用 unnset($object[$key]) 时激活
	 *
	 * @param mixed $key 键
	 * @since 1.0
	 */
	function offsetUnset($key) {
		switch ($this->_type($key)) {
			case "flash":
				$this->flash()->remove($key);
				break;
			case "session":
				$this->session()->remove($key);
				break;
			case "cookie":
				$cookie = new ICookie($key, null);
				$cookie->setMaxAge(-1);
				$cookie->setPath("/");
				$cookie->send();
				break;
			case "request":
				$this->request()->remove($key);
				break;
			case "config":
				o("@{$key}", null);
				break;
			case "message":
				break;
			default:
				$this->request()->remove($key);
		}
	}
	
	function __get($name) {
		$value = null;
		try {
			$value = parent::__get($name);
		} catch (IException $e) {
			
		}
		if (is_null($value)) {
			$value = $this->request()->param($name);
		}
		return $value;
	}
}

?>